package com.frinder.demo.line;

import com.frinder.base.HeartbeatHandler;
import com.frinder.base.server.ClientManagerHandler;
import com.frinder.base.server.Server;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

import static com.frinder.base.ByteBufUtils.buf;
import static com.frinder.base.ByteBufUtils.str;
import static com.frinder.base.Conf.*;

/**
 * @ClassName LineServer
 * @Description 基于行来进行消息处理服务端
 * @Author frinder
 * @Date 2019/4/17 11:38
 * @Verion 1.0
 */
@Slf4j
public class LineServer extends Server {

    public static void main(String[] args) {
        new LineServer().start();
    }

    @Override
    public ChannelInitializer getServerChannelInitializer() {
        return new ChannelInitializer() {
            @Override
            protected void initChannel(Channel channel) {
                log.debug("*** 初始化渠道链！");
                ChannelPipeline pipeline = channel.pipeline();
                // 日志处理器
                pipeline.addLast(new LoggingHandler(LogLevel.WARN));
                // 解码
                pipeline.addLast(new LineBasedFrameDecoder(1024));
                // 心跳检测机制
                pipeline.addLast(new IdleStateHandler(READ_IDL_TIME_OUT, WRITE_IDL_TIME_OUT, ALL_IDL_TIME_OUT, TimeUnit.SECONDS));
                pipeline.addLast(new HeartbeatHandler());
                // 客户端监听机制
                pipeline.addLast(new ClientManagerHandler(channels));
                // 服务端消息处理机制，必须放置在处理链最后
                pipeline.addLast(new LineServerHandler());
                log.debug("*** 渠道链初始化完成！");
            }
        };
    }

    class LineServerHandler extends SimpleChannelInboundHandler<ByteBuf> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) {
            log.info("*** >> 服务端接收消息：{}", str(buf));
            ctx.writeAndFlush(buf("你好啊！", "\n"));
        }

        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
            super.exceptionCaught(ctx, cause);
            ctx.close();
        }
    }
}
